package ar.com.temporis.framework.persistence;

import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.Random;

import org.apache.commons.lang.math.RandomUtils;
import org.hibernate.Criteria;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

/**
 * 
 * Este DAO sirve como helper para los tests de persistencia. Esta basado en
 * {@link HibernateDaoSupport} de spring y brinda las operaciones basicas.
 * 
 * @author matias.sulik 
 * 
 */
public class PersistenceTestDAO extends HibernateDaoSupport {

    /**
     * Realiza un clear a la sesion de hibernate
     */
    public void clear() {
        getHibernateTemplate().clear();
    }

    /**
     * Borra una entidad.
     * 
     * @param instance
     *            Instancia de una entidad.
     */
    public void delete(Object instance) {
        getHibernateTemplate().delete(instance);
    }

    /**
     * Realiza un flush a la sesion de hibernate
     */
    public void flush() {
        getHibernateTemplate().flush();
    }

    /**
     * Inserta una entidad.
     * 
     * @param instance
     *            Instancia de entidad.
     */
    public void insert(Object instance) {
        getHibernateTemplate().save(instance);
    }

    /**
     * Persiste una entidad.
     * 
     * @param instance
     *            Instancia de una entidad.
     */
    public void persist(Object instance) {
        getHibernateTemplate().saveOrUpdate(instance);
    }

    /**
     * Obtiene una entidad.
     * 
     * @param id
     *            Identificador de la entidad
     * @param clazz
     *            Clase de la entidad
     * 
     * @return Instancia de la entidad
     */
    public < T1 > T1 read(Serializable id, Class< T1 > clazz) {
        return (T1) getHibernateTemplate().load(clazz, id);
    }

    /**
     * Actualiza una entidad.
     * 
     * @param instance
     *            Instancia de una entidad.
     */
    public void update(Object instance) {
        getHibernateTemplate().update(instance);
    }
    
	protected Criteria createCriteria(Class<?> persistedType) {
		return getSession().createCriteria(persistedType);
	}

    public <T1> T1 getAny(Class<T1> clazz) {
		List<T1> list = this.createCriteria(clazz).setMaxResults(10).list();

		int index = 0;

		if (list.size() > 1) {
			index = RandomUtils.nextInt(new Random(new Date().getTime()), list.size());
		}

		return list.get(index);
	}

}
